﻿using System;
using System.Web.DynamicData;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Expressions;

namespace PD.Web.DynamicData.PageTemplates
{
    /// <summary>
    /// View detailed information about single entity page.
    /// </summary>
    public partial class ListDetails : System.Web.UI.Page
    {
        /// <summary>
        /// The metadata that describes a table for use by Dynamic Data pages.
        /// </summary>
        private MetaTable table;

        /// <summary>
        /// Handles the Init event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Init(object sender, EventArgs e)
        {
            this.table = DynamicDataRouteHandler.GetRequestMetaTable(this.Context);
            this.GridView1.SetMetaTable(this.table, this.table.GetColumnValuesFromRoute(this.Context));
            this.FormView1.SetMetaTable(this.table);
            this.GridDataSource.EntityTypeName = this.table.EntityType.AssemblyQualifiedName;
            this.DetailsDataSource.EntityTypeName = this.table.EntityType.AssemblyQualifiedName;
            if (this.table.EntityType != this.table.RootEntityType)
            {
                this.GridQueryExtender.Expressions.Add(new OfTypeExpression(this.table.EntityType));
            }
        }

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            this.Title = this.table.DisplayName;

            // Selection from url
            if (!this.Page.IsPostBack && this.table.HasPrimaryKey)
            {
                this.GridView1.SelectedPersistedDataKey = this.table.GetDataKeyFromRoute();
                if (this.GridView1.SelectedPersistedDataKey == null)
                {
                    this.GridView1.SelectedIndex = 0;
                }
            }

            // Disable various options if the table is readonly
            if (this.table.IsReadOnly)
            {
                this.DetailsPanel.Visible = false;
                this.GridView1.AutoGenerateSelectButton = false;
                this.GridView1.AutoGenerateEditButton = false;
                this.GridView1.AutoGenerateDeleteButton = false;
                this.GridView1.EnablePersistedSelection = false;
            }
        }

        /// <summary>
        /// Handles the DataBound event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void GridView1_DataBound(object sender, EventArgs e)
        {
            if (this.GridView1.Rows.Count == 0)
            {
                this.FormView1.ChangeMode(FormViewMode.Insert);
            }
        }

        /// <summary>
        /// Handles the PreRender event of the Label control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Label_PreRender(object sender, EventArgs e)
        {
            Label label = (Label)sender;
            DynamicFilter dynamicFilter = (DynamicFilter)label.FindControl("DynamicFilter");
            QueryableFilterUserControl fuc = dynamicFilter.FilterTemplate as QueryableFilterUserControl;
            if (fuc != null && fuc.FilterControl != null)
            {
                label.AssociatedControlID = fuc.FilterControl.GetUniqueIDRelativeTo(label);
            }
        }

        /// <summary>
        /// Handles the FilterChanged event of the DynamicFilter control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void DynamicFilter_FilterChanged(object sender, EventArgs e)
        {
            this.GridView1.EditIndex = -1;
            this.GridView1.PageIndex = 0;
            this.FormView1.ChangeMode(FormViewMode.ReadOnly);
        }

        /// <summary>
        /// Handles the RowEditing event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void GridView1_RowEditing(object sender, EventArgs e)
        {
            this.FormView1.ChangeMode(FormViewMode.ReadOnly);
        }

        /// <summary>
        /// Handles the SelectedIndexChanging event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void GridView1_SelectedIndexChanging(object sender, EventArgs e)
        {
            this.GridView1.EditIndex = -1;
            this.FormView1.ChangeMode(FormViewMode.ReadOnly);
        }

        /// <summary>
        /// Handles the RowCreated event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param>
        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {
            this.SetDeleteConfirmation(e.Row);
        }

        /// <summary>
        /// Handles the RowDeleted event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewDeletedEventArgs"/> instance containing the event data.</param>
        protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
        {
            this.FormView1.DataBind();
        }

        /// <summary>
        /// Handles the RowUpdated event of the GridView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewUpdatedEventArgs"/> instance containing the event data.</param>
        protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
        {
            this.FormView1.DataBind();
        }

        /// <summary>
        /// Handles the ItemDeleted event of the FormView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewDeletedEventArgs"/> instance containing the event data.</param>
        protected void FormView1_ItemDeleted(object sender, FormViewDeletedEventArgs e)
        {
            this.GridView1.DataBind();
        }

        /// <summary>
        /// Handles the ItemUpdated event of the FormView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewUpdatedEventArgs"/> instance containing the event data.</param>
        protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
        {
            this.GridView1.DataBind();
        }

        /// <summary>
        /// Handles the ItemInserted event of the FormView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewInsertedEventArgs"/> instance containing the event data.</param>
        protected void FormView1_ItemInserted(object sender, FormViewInsertedEventArgs e)
        {
            this.GridView1.DataBind();
        }

        /// <summary>
        /// Handles the ModeChanging event of the FormView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewModeEventArgs"/> instance containing the event data.</param>
        protected void FormView1_ModeChanging(object sender, FormViewModeEventArgs e)
        {
            if (e.NewMode != FormViewMode.ReadOnly)
            {
                this.GridView1.EditIndex = -1;
            }
        }

        /// <summary>
        /// Handles the PreRender event of the FormView1 control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void FormView1_PreRender(object sender, EventArgs e)
        {
            if (this.FormView1.Row != null)
            {
                this.SetDeleteConfirmation(this.FormView1.Row);
            }
        }

        /// <summary>
        /// Sets the delete confirmation.
        /// </summary>
        /// <param name="row">The row.</param>
        private void SetDeleteConfirmation(TableRow row)
        {
            foreach (Control c in row.Cells[0].Controls)
            {
                LinkButton button = c as LinkButton;
                if (button != null && button.CommandName == DataControlCommands.DeleteCommandName)
                {
                    button.OnClientClick = "return confirm('Are you sure you want to delete this item?');";
                }
            }
        }
    }
}
